home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / c2man-2.0pl33.lha / c2man-2.0 / grammar.y < prev    next >
Encoding:
Text File  |  1995-01-24  |  16.6 KB  |  845 lines

  1. /* $Id: grammar.y,v 2.0.1.15 1994/05/19 01:15:15 greyham Exp $
  2.  *
  3.  * yacc grammar for C manual page generator
  4.  * This was derived from the grammar given in Appendix A of
  5.  * "The C Programming Language" by Kernighan and Ritchie.
  6.  */
  7.  
  8. /* identifiers that are not reserved words */
  9. %token T_IDENTIFIER T_TYPEDEF_NAME
  10.  
  11. /* storage class */
  12. %token T_AUTO T_EXTERN T_REGISTER T_STATIC T_TYPEDEF
  13. /* This keyword included for compatibility with C++. */
  14. %token T_INLINE
  15.  
  16. /* type specifiers */
  17. %token T_CHAR T_DOUBLE T_FLOAT T_INT T_VOID
  18. %token T_LONG T_SHORT T_SIGNED T_UNSIGNED
  19. %token T_ENUM T_STRUCT T_UNION
  20.  
  21. /* type qualifiers */
  22. %token T_CONST T_VOLATILE
  23. /* These keywords included for compatibility with MSDOS C compilers. */
  24. %token T_CDECL T_FAR T_HUGE T_INTERRUPT T_NEAR T_PASCAL
  25.  
  26. /* paired braces and everything between them: { ... } */
  27. %token T_BRACES
  28.  
  29. /* paired square brackets and everything between them: [ ... ] */
  30. %token T_BRACKETS
  31.  
  32. /* three periods */
  33. %token T_ELLIPSIS
  34.  
  35. /* equal sign followed by constant expression or stuff between braces */
  36. %token T_INITIALIZER
  37.  
  38. /* string literal */
  39. %token T_STRING_LITERAL
  40.  
  41. /* text inside a regular comment, and one at the end of a non-empty line */
  42. %token T_COMMENT T_EOLCOMMENT
  43.  
  44. /* whenever we change include files */
  45. %token T_BASEFILE
  46.  
  47. %type <declaration> declaration
  48. %type <parameter> function_definition
  49. %type <decl_spec> declaration_specifiers declaration_specifier
  50. %type <decl_spec> storage_class type_specifier type_qualifier
  51. %type <decl_spec> struct_or_union_specifier enum_specifier
  52. %type <decl_list> declarator_list init_declarator_list
  53. %type <declarator> init_declarator declarator direct_declarator
  54. %type <declarator> abstract_declarator direct_abstract_declarator
  55. %type <param_list> parameter_type_list parameter_list
  56. %type <parameter> parameter_declaration
  57. %type <param_list> opt_identifier_list identifier_list
  58. %type <enumerator> enumerator
  59. %type <enum_list> enumerator_list
  60. %type <identifier> identifier
  61. %type <text> struct_or_union
  62. %type <text> pointer type_qualifier_list
  63. %type <text> opt_comment opt_eolcomment
  64. %type <text> any_id T_IDENTIFIER T_TYPEDEF_NAME
  65. %type <text> T_BRACKETS
  66. %type <text> T_COMMENT T_EOLCOMMENT T_STRING_LITERAL
  67. %type <boolean> T_BASEFILE
  68.  
  69. %{
  70. #include "c2man.h"
  71. #include "semantic.h"
  72. #include "strconcat.h"
  73. #include "strappend.h"
  74. #include "manpage.h"
  75. #include "enum.h"
  76.  
  77. #ifdef I_STDARG
  78. #include <stdarg.h>
  79. #endif
  80. #ifdef I_VARARGS
  81. #include <varargs.h>
  82. #endif
  83.  
  84. int yylex();
  85.  
  86. #define YYMAXDEPTH 150
  87.  
  88. /* where are we up to scanning through an enum? */
  89. static enum { NOENUM, KEYWORD, BRACES } enum_state = NOENUM;
  90.  
  91. /* Pointer to parameter list for the current function definition. */
  92. static ParameterList *func_params;
  93.  
  94. /* Table of typedef names */
  95. SymbolTable *typedef_names;
  96.  
  97. boolean first_comment;    /* are we still looking for the first comment? */
  98. %}
  99. %%
  100.  
  101. program
  102.     : /* empty */
  103.     | translation_unit
  104.     ;
  105.  
  106. translation_unit
  107.     : external_declaration
  108.     | translation_unit external_declaration
  109.     ;
  110.  
  111. external_declaration
  112.     : declaration opt_eolcomment
  113.     {
  114.         remember_declarations(NULL, &$1.decl_spec, &$1.decl_list, $2);
  115.     }
  116.     | T_COMMENT declaration opt_eolcomment
  117.     {
  118.         remember_declarations($1, &$2.decl_spec, &$2.decl_list, $3);
  119.     }
  120.     | function_definition opt_eolcomment
  121.     {
  122.         free_declarator($1.declarator);
  123.         free_decl_spec(&$1.decl_spec);
  124.         safe_free($2);
  125.     }
  126.     | T_COMMENT function_definition opt_eolcomment
  127.     {
  128.         new_manual_page($1,&$2.decl_spec,$2.declarator);
  129.         safe_free($3);
  130.     }
  131.     | function_definition ';' opt_eolcomment
  132.     {
  133.         free_declarator($1.declarator);
  134.         free_decl_spec(&$1.decl_spec);
  135.         safe_free($3);
  136.     }
  137.     | T_COMMENT function_definition ';' opt_eolcomment
  138.     {
  139.         new_manual_page($1,&$2.decl_spec,$2.declarator);
  140.         safe_free($4);
  141.     }
  142.     | linkage_specification
  143.     | T_COMMENT
  144.     {
  145.         if (inbasefile && first_comment)
  146.         {
  147.         remember_terse($1);
  148.         first_comment = FALSE;
  149.         }
  150.         free($1);
  151.     }
  152.     | T_EOLCOMMENT
  153.     {
  154.         free($1);
  155.     }
  156.     | T_BASEFILE
  157.     {
  158.         inbasefile = $1;
  159.     }
  160.     | error ';'
  161.     {
  162.         yyerrok;
  163.     }
  164.     ;
  165.  
  166. linkage_specification
  167.     : T_EXTERN T_STRING_LITERAL T_BRACES
  168.     {
  169.         /* Provide an empty action here so bison will not complain about
  170.          * incompatible types in the default action it normally would
  171.          * have generated.
  172.          */
  173.     }
  174.     | T_EXTERN T_STRING_LITERAL declaration
  175.     {
  176.         /* empty */
  177.     }
  178.     ;
  179.  
  180. function_definition
  181.     : declaration_specifiers declarator opt_eolcomment
  182.     {
  183.         if ($2->type != DECL_FUNCTION) {
  184.         yyerror("syntax error");
  185.         YYERROR;
  186.         }
  187.         func_params = &($2->head->params);
  188.             if ($3)    comment_last_parameter(&$2->head->params, $3);
  189.     }
  190.       opt_declaration_list T_BRACES
  191.     {
  192.         func_params = NULL;
  193.         $2->type = DECL_FUNCDEF;
  194.  
  195.         $$.decl_spec = $1;
  196.         $$.declarator = $2;
  197.     }
  198.     | declarator opt_eolcomment
  199.     {
  200.         if ($1->type != DECL_FUNCTION) {
  201.         yyerror("syntax error");
  202.         YYERROR;
  203.         }
  204.         func_params = &($1->head->params);
  205.             if ($2)    comment_last_parameter(&$1->head->params, $2);
  206.     }
  207.       opt_declaration_list T_BRACES
  208.     {
  209.         DeclSpec    decl_spec;
  210.  
  211.         func_params = NULL;
  212.         $1->type = DECL_FUNCDEF;
  213.  
  214.         new_decl_spec(&$$.decl_spec, "int", DS_NONE);
  215.         $$.declarator = $1;
  216.     }
  217.     ;
  218.  
  219. declaration
  220.     : declaration_specifiers ';'
  221.     {
  222.         $$.decl_spec = $1;
  223.         $$.decl_list.first = NULL;
  224.     }
  225.     | declaration_specifiers init_declarator_list ';'
  226.     {
  227.         $$.decl_spec = $1;
  228.         $$.decl_list = $2;
  229.     }
  230.     | T_TYPEDEF declaration_specifiers declarator_list ';'
  231.     {
  232.         new_typedef_symbols(&$2,&$3);
  233.         $$.decl_spec = $2;
  234.         $$.decl_list = $3;
  235.     }
  236.     ;
  237.  
  238. declarator_list
  239.     : declarator
  240.     {
  241.         new_decl_list(&$$, $1);
  242.     }
  243.         | declarator_list ',' opt_eolcomment declarator
  244.         {
  245.             if ($3)    comment_last_decl(&$1, $3);
  246.             add_decl_list(&$$, &$1, $4);
  247.         }
  248.         | declarator_list opt_eolcomment
  249.         {
  250.             $$ = $1;
  251.             if ($2)    comment_last_decl(&$1, $2);
  252.         }
  253.     ;
  254.  
  255. opt_declaration_list
  256.     : /* empty */
  257.     | declaration_list
  258.     | declaration_list T_ELLIPSIS
  259.     ;
  260.  
  261. declaration_list
  262.     : opt_comment declaration opt_eolcomment
  263.     {
  264.         set_param_types(func_params, &$2.decl_spec, &$2.decl_list, $1, $3);
  265.     }
  266.     | declaration_list opt_comment declaration opt_eolcomment
  267.     {
  268.         set_param_types(func_params, &$3.decl_spec, &$3.decl_list, $2, $4);
  269.     }
  270.     ;
  271.  
  272. declaration_specifiers
  273.     : declaration_specifier
  274.     | declaration_specifiers declaration_specifier
  275.     {
  276.         join_decl_specs(&$$, &$1, &$2);
  277.     }
  278.     ;
  279.  
  280. declaration_specifier
  281.     : storage_class
  282.     | type_specifier
  283.     | type_qualifier
  284.     ;
  285.  
  286. storage_class
  287.     : T_AUTO
  288.     {
  289.         new_decl_spec(&$$, "auto", DS_NONE);
  290.     }
  291.     | T_EXTERN
  292.     {
  293.         new_decl_spec(&$$, "extern", DS_EXTERN);
  294.     }
  295.     | T_REGISTER
  296.     {
  297.         new_decl_spec(&$$, "register", DS_NONE);
  298.     }
  299.     | T_STATIC
  300.     {
  301.         new_decl_spec(&$$, "static", DS_STATIC);
  302.     }
  303.     | T_INLINE
  304.     {
  305.         new_decl_spec(&$$, "inline", DS_INLINE);
  306.     }
  307.     ;
  308.  
  309. type_specifier
  310.     : T_CHAR
  311.     {
  312.         new_decl_spec(&$$, "char", DS_CHAR);
  313.     }
  314.     | T_DOUBLE
  315.     {
  316.         new_decl_spec(&$$, "double", DS_NONE);
  317.     }
  318.     | T_FLOAT
  319.     {
  320.         new_decl_spec(&$$, "float", DS_FLOAT);
  321.     }
  322.     | T_INT
  323.     {
  324.         new_decl_spec(&$$, "int", DS_NONE);
  325.     }
  326.     | T_LONG
  327.     {
  328.         new_decl_spec(&$$, "long", DS_NONE);
  329.     }
  330.     | T_SHORT
  331.     {
  332.         new_decl_spec(&$$, "short", DS_SHORT);
  333.     }
  334.     | T_SIGNED
  335.     {
  336.         new_decl_spec(&$$, "signed", DS_NONE);
  337.     }
  338.     | T_UNSIGNED
  339.     {
  340.         new_decl_spec(&$$, "unsigned", DS_NONE);
  341.     }
  342.     | T_VOID
  343.     {
  344.         new_decl_spec(&$$, "void", DS_NONE);
  345.     }
  346.     | struct_or_union_specifier
  347.     | enum_specifier
  348.     | T_TYPEDEF_NAME
  349.     {
  350.         Symbol *s = find_symbol(typedef_names, $1);
  351.        
  352.         new_enum_decl_spec(&$$, $1, s->flags,
  353.         s->valtype == SYMVAL_ENUM ? s->value.enum_list
  354.                       : (EnumeratorList *)NULL);
  355.     }
  356.     ;
  357.  
  358. type_qualifier
  359.     : T_CONST
  360.     {
  361.         new_decl_spec(&$$, "const", DS_NONE);
  362.     }
  363.     | T_VOLATILE
  364.     {
  365.         new_decl_spec(&$$, "volatile", DS_NONE);
  366.     }
  367.     | T_CDECL
  368.     {
  369.         new_decl_spec(&$$, "cdecl", DS_NONE);
  370.     }
  371.     | T_INTERRUPT
  372.     {
  373.         new_decl_spec(&$$, "interrupt", DS_NONE);
  374.     }
  375.     | T_FAR
  376.     {
  377.         new_decl_spec(&$$, "far", DS_NONE);
  378.     }
  379.     | T_HUGE
  380.     {
  381.         new_decl_spec(&$$, "huge", DS_NONE);
  382.     }
  383.     | T_NEAR
  384.     {
  385.         new_decl_spec(&$$, "near", DS_NONE);
  386.     }
  387.     | T_PASCAL
  388.     {
  389.         new_decl_spec(&$$, "pascal", DS_NONE);
  390.     }
  391.     ;
  392.  
  393. struct_or_union_specifier
  394.     : struct_or_union any_id T_BRACES
  395.     {
  396.         dyn_decl_spec(&$$, strconcat($1, " ",$2," {}",NULLCP), DS_NONE);
  397.         free($2);
  398.     }
  399.     | struct_or_union T_BRACES
  400.     {
  401.         dyn_decl_spec(&$$, strconcat($1," {}",NULLCP), DS_NONE);
  402.     }
  403.     | struct_or_union any_id
  404.     {
  405.         dyn_decl_spec(&$$, strconcat($1, " ",$2,NULLCP), DS_NONE);
  406.         free($2);
  407.     }
  408.     ;
  409.  
  410. struct_or_union
  411.     : T_STRUCT
  412.     {
  413.         $$ = "struct";
  414.     }
  415.     | T_UNION
  416.     {
  417.         $$ = "union";
  418.     }
  419.     ;
  420.  
  421. init_declarator_list
  422.     : init_declarator
  423.     {
  424.         new_decl_list(&$$, $1);
  425.     }
  426.         | init_declarator_list ',' opt_eolcomment init_declarator
  427.         {
  428.             if ($3)    comment_last_decl(&$1, $3);
  429.             add_decl_list(&$$, &$1, $4);
  430.         }
  431.         | init_declarator_list opt_eolcomment
  432.         {
  433.             $$ = $1;
  434.             if ($2)    comment_last_decl(&$1, $2);
  435.         }
  436.     ;
  437.  
  438. init_declarator
  439.     : declarator
  440.     | declarator T_INITIALIZER
  441.     ;
  442.  
  443. enum_specifier
  444.     : T_ENUM any_id '{' opt_eolcomment enumerator_list '}'
  445.     {
  446.         add_enum_symbol($2, $5);
  447.         new_enum_decl_spec(&$$, strconcat("enum ",$2," {}",NULLCP),
  448.            DS_NONE, $5);
  449.         free($2);
  450.         safe_free($4);
  451.         enum_state = NOENUM;
  452.     }
  453.     | T_ENUM '{' opt_eolcomment enumerator_list '}'
  454.     {
  455.         new_enum_decl_spec(&$$, strduplicate("enum {}"), DS_NONE, $4);
  456.         safe_free($3);
  457.         enum_state = NOENUM;
  458.     }
  459.     | T_ENUM any_id
  460.     {
  461.         new_enum_decl_spec(&$$, strconcat("enum ",$2,NULLCP), DS_NONE,
  462.             find_enum_symbol($2));
  463.         free($2);
  464.         enum_state = NOENUM;
  465.     }
  466.     ;
  467.  
  468. enumerator_list
  469.     : enumerator
  470.     {
  471.         $$ = new_enumerator_list(&$1);
  472.     }
  473.     | enumerator_list ',' opt_eolcomment enumerator
  474.     {
  475.         $$ = $1;
  476.         if ($3)    comment_last_enumerator($$, $3);
  477.         add_enumerator_list($$, &$4);
  478.     }
  479.     | enumerator_list opt_eolcomment
  480.     {
  481.         $$ = $1;
  482.         if ($2)    comment_last_enumerator($$, $2);
  483.     }
  484.     | enumerator_list ',' opt_eolcomment
  485.     {
  486.         $$ = $1;
  487.         if ($3)     comment_last_enumerator($$, $3);
  488.     }
  489.     ;
  490.     
  491. enumerator
  492.     : identifier
  493.     {
  494.         new_enumerator(&$$,$1.name,$1.comment_before,$1.comment_after);
  495.     }
  496.     ;
  497.     
  498. any_id
  499.     : T_IDENTIFIER
  500.     | T_TYPEDEF_NAME
  501.     | any_id T_COMMENT
  502.     {
  503.         $$ = $1;
  504.         free($2);
  505.     }
  506.     | any_id T_EOLCOMMENT
  507.     {
  508.         $$ = $1;
  509.         free($2);
  510.     }
  511.     ;
  512.  
  513. declarator
  514.     : pointer direct_declarator
  515.     {
  516.         char *newtext = strappend($1,$2->text,NULLCP);
  517.         free($2->text);
  518.         $$ = $2;
  519.         $$->text = newtext;
  520.         if ($$->type == DECL_SIMPLE)
  521.         $$->type = DECL_COMPOUND;
  522.     }
  523.     | direct_declarator
  524.     ;
  525.  
  526. direct_declarator
  527.     : T_IDENTIFIER
  528.     {
  529.         $$ = new_declarator($1, strduplicate($1));
  530.     }
  531.     | '(' declarator ')'
  532.     {
  533.         char *newtext = strconcat("(",$2->text,")",NULLCP);
  534.         free($2->text);
  535.         $$ = $2;
  536.         $$->text = newtext;
  537.     }
  538.     | direct_declarator T_BRACKETS
  539.     {
  540.         $$ = $1;
  541.         $$->text = strappend($1->text,$2,NULLCP);
  542.         free($2);
  543.     }
  544.     | direct_declarator '(' parameter_type_list ')'
  545.     {
  546.         $$ = new_declarator(strduplicate("%s()"), strduplicate($1->name));
  547.         $$->params = $3;
  548.         $$->func_stack = $1;
  549.         $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
  550.         $$->type = ($1->type == DECL_SIMPLE) ? DECL_FUNCTION : $1->type;
  551.     }
  552.     | direct_declarator '(' opt_identifier_list ')'
  553.     {
  554.         $$ = new_declarator(strduplicate("%s()"), strduplicate($1->name));
  555.         $$->params = $3;
  556.         $$->func_stack = $1;
  557.         $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
  558.         $$->type = ($1->type == DECL_SIMPLE) ? DECL_FUNCTION : $1->type;
  559.     }
  560.     ;
  561.  
  562. pointer
  563.     : '*' type_qualifier_list
  564.     {
  565.         $$ = strconcat("*",$2, NULLCP);
  566.         safe_free($2);
  567.     }
  568.     | '*' type_qualifier_list pointer
  569.     {
  570.         $$ = $2 ? strconcat("*",$2, $3, NULLCP)
  571.             : strconcat("*", $3, NULLCP);
  572.         safe_free($2);
  573.         free($3);
  574.     }
  575.     ;
  576.  
  577. type_qualifier_list
  578.     : /* empty */
  579.     {
  580.         $$ = NULL;
  581.     }
  582.     | type_qualifier_list type_qualifier
  583.     {
  584.         $$ = $1 ? strconcat($1," ",$2.text," ",NULLCP)
  585.             : strconcat($2.text," ",NULLCP);
  586.         safe_free($1);
  587.         free_decl_spec(&$2);
  588.     }
  589.     ;
  590.  
  591. parameter_type_list
  592.     : parameter_list opt_eolcomment
  593.     {
  594.         $$ = $1;
  595.         if ($2)    comment_last_parameter(&$1, $2);
  596.     }
  597.     | parameter_list ',' opt_eolcomment
  598.         opt_comment T_ELLIPSIS opt_comment opt_eolcomment
  599.     {
  600.         Identifier ellipsis;
  601.  
  602.         if ($3)    comment_last_parameter(&$1, $3);
  603.         ellipsis.name = strduplicate("...");
  604.  
  605.         if ($4 && $6 && $7)
  606.         {
  607.         yyerror("ellipsis parameter has multiple comments");
  608.         free($7);
  609.         free($6);
  610.         free($4);
  611.         ellipsis.comment_before = ellipsis.comment_after = NULL;
  612.         }
  613.         else
  614.         {
  615.         ellipsis.comment_before = $4;
  616.         ellipsis.comment_after = $6 ? $6 : $7;
  617.         }
  618.  
  619.         add_ident_list(&$$, &$1, &ellipsis);
  620.     }
  621.     ;
  622.  
  623. parameter_list
  624.     : parameter_declaration
  625.     {
  626.         new_param_list(&$$, &$1);
  627.     }
  628.     | parameter_list ',' opt_eolcomment parameter_declaration
  629.     {
  630.         if ($3)    comment_last_parameter(&$1, $3);
  631.         add_param_list(&$$, &$1, &$4);
  632.     }
  633.     ;
  634.  
  635. parameter_declaration
  636.     : opt_comment declaration_specifiers declarator opt_comment
  637.     {
  638.         new_parameter(&$$, &$2, $3, $1, $4);
  639.     }
  640.     | opt_comment declaration_specifiers abstract_declarator opt_comment
  641.     {
  642.         new_parameter(&$$, &$2, $3, $1, $4);
  643.     }
  644.     | opt_comment declaration_specifiers opt_comment
  645.     {
  646.         new_parameter(&$$, &$2, (Declarator *)NULL, $1, $3);
  647.     }
  648.     ;
  649.  
  650. opt_identifier_list
  651.     : /* empty */
  652.     {
  653.         new_ident_list(&$$);
  654.     }
  655.     | identifier_list opt_eolcomment
  656.     {
  657.         $$ = $1;
  658.         if ($2)    comment_last_parameter(&$1, $2);
  659.     }
  660.     ;
  661.  
  662. identifier_list
  663.     : identifier
  664.     {
  665.         new_ident_list(&$$);
  666.         add_ident_list(&$$, &$$, &$1);
  667.     }
  668.     | identifier_list ',' opt_eolcomment identifier
  669.     {
  670.         if ($3)    comment_last_parameter(&$1, $3);
  671.         add_ident_list(&$$, &$1, &$4);
  672.     }
  673.     ;
  674.  
  675. identifier
  676.     : opt_comment T_IDENTIFIER opt_comment
  677.     {
  678.         $$.comment_before = $1;
  679.         $$.comment_after = $3;
  680.         $$.name = $2;
  681.     }
  682.     
  683. abstract_declarator
  684.     : pointer
  685.     {
  686.         $$ = new_declarator($1, NULLCP);
  687.     }
  688.     | pointer direct_abstract_declarator
  689.     {
  690.         char *newtext = strappend($1,$2->text,NULLCP);
  691.         free($2->text);
  692.         $$ = $2;
  693.         $$->text = newtext;
  694.         if ($$->type == DECL_SIMPLE)
  695.         $$->type = DECL_COMPOUND;
  696.     }
  697.     | direct_abstract_declarator
  698.     ;
  699.  
  700. direct_abstract_declarator
  701.     : '(' abstract_declarator ')'
  702.     {
  703.         char *newtext = strconcat("(",$2->text,")",NULLCP);
  704.         free($2->text);
  705.         $$ = $2;
  706.         $$->text = newtext;
  707.     }
  708.     | direct_abstract_declarator T_BRACKETS
  709.     {
  710.         $$ = $1;
  711.         $$->text = strappend($1->text,$2,NULLCP);
  712.         free($2);
  713.     }
  714.     | T_BRACKETS
  715.     {
  716.         $$ = new_declarator($1, NULLCP);
  717.     }
  718.     | direct_abstract_declarator '(' parameter_type_list ')'
  719.     {
  720.         $$ = new_declarator(strduplicate("%s()"), NULLCP);
  721.         $$->params = $3;
  722.         $$->func_stack = $1;
  723.         $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
  724.         $$->type = ($1->type == DECL_SIMPLE) ? DECL_FUNCTION : $1->type;
  725.     }
  726.     | direct_abstract_declarator '(' ')'
  727.     {
  728.         $$ = new_declarator(strduplicate("%s()"), NULLCP);
  729.         $$->func_stack = $1;
  730.         $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
  731.         $$->type = ($1->type == DECL_SIMPLE) ? DECL_FUNCTION : $1->type;
  732.     }
  733.     | '(' parameter_type_list ')'
  734.     {
  735.         Declarator *d;
  736.         
  737.         d = new_declarator(NULL, NULL);
  738.         $$ = new_declarator(strduplicate("%s()"), NULLCP);
  739.         $$->params = $2;
  740.         $$->func_stack = d;
  741.         $$->head = $$;
  742.     }
  743.     | '(' ')'
  744.     {
  745.         Declarator *d;
  746.         
  747.         d = new_declarator(NULL, NULL);
  748.         $$ = new_declarator(strduplicate("%s()"), NULLCP);
  749.         $$->func_stack = d;
  750.         $$->head = $$;
  751.     }
  752.     ;
  753.  
  754. opt_comment
  755.     : /* empty */
  756.     {
  757.         $$ = NULL;
  758.     }
  759.     | T_COMMENT
  760.     ;
  761.  
  762. opt_eolcomment
  763.     : /* empty */
  764.     {
  765.         $$ = NULL;
  766.     }
  767.     | T_EOLCOMMENT
  768.     ;
  769.  
  770. %%
  771. #ifdef MSDOS
  772. #include "lex_yy.c"
  773. #else
  774. #ifdef VMS
  775. #include "lexyy.c"
  776. #else
  777. #include "lex.yy.c"
  778. #endif /* !VMS   */
  779. #endif /* !MSDOS */
  780.  
  781. #ifdef I_STDARG
  782. void yyerror(const char *format, ...)
  783. #else
  784. void yyerror(va_alist)
  785.     va_dcl
  786. #endif
  787. {
  788. #ifndef I_STDARG
  789.     const char *format;
  790. #endif
  791.     va_list args;
  792.  
  793.     output_error();
  794.  
  795. #ifdef I_STDARG
  796.     va_start(args, format);
  797. #else
  798.     va_start(args);
  799.     format = va_arg(args, char *);
  800. #endif
  801.  
  802.     vfprintf(stderr, format, args);
  803.     va_end(args);
  804.     putc('.',stderr);
  805.     putc('\n',stderr);
  806. }
  807.  
  808. void
  809. parse_file (start_file)
  810. const char *start_file;
  811. {
  812.     const char *s;
  813. #ifdef FLEX_SCANNER
  814.     static boolean restart = FALSE;
  815. #endif
  816.  
  817.     cur_file = start_file ? strduplicate(start_file) : NULL;
  818.  
  819.     if (basefile && strlen(basefile) > 2) {
  820.     s = basefile + strlen(basefile) - 2;
  821.     if (strcmp(s, ".l") == 0 || strcmp(s, ".y") == 0)
  822.         BEGIN LEXYACC;
  823.     }
  824.  
  825.     typedef_names = create_symbol_table();
  826.     enum_table = create_symbol_table();
  827.  
  828.     line_num = 1;
  829.     ly_count = 0;
  830.     first_comment = group_together && !terse_specified;
  831.  
  832.     /* flex needs a yyrestart before every file but the first */
  833. #ifdef FLEX_SCANNER
  834.     if (restart)    yyrestart(yyin);
  835.     restart = TRUE;
  836. #endif
  837.  
  838.     yyparse();
  839.  
  840.     destroy_symbol_table(enum_table);
  841.     destroy_symbol_table(typedef_names);
  842.  
  843.     safe_free(cur_file);
  844. }
  845.